package com.wb.iec104.analysis;


import com.wb.iec104.utils.Util;

public class ASDU {


    public static void ASDU_analysis(int[] asdu) {
        String s = String.valueOf(asdu[2] & 0x3F);
        int info[] = new int[asdu.length - 6];
        // 将[信息元素+限定词+（时标）]装入数组info
        for (int i = 0; i < info.length; i++) {
            info[i] = asdu[6 + i];
        }
        Infoanalysis(info, asdu[0], ((asdu[1] & 0x80) >> 7), (asdu[1] & 0x7f));

    }

    /**
     * @param info 信息地址+信息元素+限定词+（时标）
     * @param i    类型标识
     * @param j    SQ
     * @param k    信息体个数
     * @return
     * @throws Exception
     */
    private static void Infoanalysis(int[] info, int i, int j, int k) {
        switch (i) {
            case 1:
                TelemetryIEC104.NoTime_Point(info, k, i, j);
                break;
            case 3:
                TelemetryIEC104.NoTime_Point(info, k, i, j);
                break;
            case 9:// 测量值，归一化值（遥测）*
                TelesignallingIEC104.normalization(info, k, i, j);
                break;
            case 11:// 测量值，标度化值（遥测）
                break;
            case 13:// 测量值，短浮点数（遥测）
                TelesignallingIEC104.short_float(info, k, i, j);
                break;
            case 21:// 测量值，归一化值（遥测）*
                TelesignallingIEC104.normalizationNoDqs(info, k, i, j);
                break;
            case 30:
                TelemetryIEC104.Time_Point(info, k, i, j);
                break;
            case 31:
                break;
            case 36:
                TelesignallingIEC104.Time_Point_Short_Flaot(info, k, i, j);
                break;

            case 70:
                InfoAddress(info[0], info[1], info[2]);
                break;
            //待补充
            // 单命令（遥控）
            case 45:
            case 46:// 双命令（遥控）
            case 48:
            case 100:
            case 102:
            case 103:
            case 105:
            case 132:
            case 136:
            default:
                break;
        }

    }

    /**
     * 信息对象地址转换
     *
     * @param i bit0 ~bit7
     * @param j bit8 ~bit15
     * @param k bit16 ~bit23
     * @return 十进制地址（十六进制地址）
     */
    public static String InfoAddress(int i, int j, int k) {

        int add;
        add = (k << 16) + (j << 8) + i;
        return String.valueOf(add);
    }

    /**
     * 信息对象地址转换
     *
     * @param i bit0 ~bit7
     * @param j bit8 ~bit15
     * @param k bit16 ~bit23
     * @return 十进制地址（十六进制地址）
     */
    public static int infoAddress(int i, int j, int k) {

        int add;
        add = (k << 16) + (j << 8) + i;
        return add;
    }

    /**
     * 归一化信息提地址信息对象地址转换
     *
     * @param i bit0 ~bit7
     * @param j bit8 ~bit15
     * @return 十进制地址（十六进制地址）
     */
    public static int infoAddress(int i, int j) {

        int add;
        add = (j << 8) + i;
        return add;
    }

    /**
     * 解析传送原因
     *
     * @param i
     * @param j
     * @return
     */
    public static String CotAnalysis(int i, int j) {
        StringBuilder builder = new StringBuilder();
        if ((i & 0x80) == 128) {
            builder.append("[T(test) bit7:1   实验]");
        } else if ((i & 0x80) == 0) {
            builder.append("[T(test) bit7:0  未实验]");
        }
        if ((i & 0x40) == 64) {
            builder.append("[P/N  bit6:1  否定确认]");
        } else if ((i & 0x40) == 0) {
            builder.append("[P/N  bit6:0  肯定确认]");
        }
        return builder.toString();
    }

    /**
     * 解析可变结构限定词
     *
     * @param b
     * @return
     */
    private static String VariTureDete(int b) {
        String vvString = "可变结构限定词:";
        vvString += Util.toHexString(b);
        vvString += "   ";
        if ((b & 0x80) == 128) {
            vvString += "SQ=1 信息元素地址顺序     ";
        } else if ((b & 0x80) == 0) {
            vvString += "SQ=0  信息元素地址非顺序     ";
        }
        vvString += "信息元素个数：";
        vvString += b & 0x7f;
        return vvString;
    }
}
